package common;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Hashtable;

import objects.Item;
import objects.Map;
import objects.Monster;
import objects.MonsterGroup;
import objects.Spell;
import objects.SubArea;
import objects.Trigger;

public class LoadingData {

    private static ArrayList<String[]> expTable = new ArrayList<String[]>();
    private static ArrayList<String[]> raceDatas = new ArrayList<String[]>();
    private static Hashtable<Integer, Map> mapDatas = new Hashtable<Integer, Map>();
    private static Hashtable<Integer, Trigger> triggerDatas = new Hashtable<Integer, Trigger>();
    private static Hashtable<Integer, Item> itemDatas = new Hashtable<Integer, Item>();
    private static Hashtable<Integer, Monster> monsterDatas = new Hashtable<Integer, Monster>();
    private static Hashtable<Long, SubArea> subAreaDatas = new Hashtable<Long, SubArea>();
    private static Hashtable<Long, Spell> spellDatas = new Hashtable<Long, Spell>();

    public LoadingData() {
    }

    public static void loadExp() {
        Statement stat = SQLMgr.createStat();
        ResultSet result = SQLMgr.query(stat, "SELECT * FROM exp_table ORDER BY lvl");

        try {
            String[] eData = new String[5];

            while (result.next()) {
                eData[0] = result.getString("lvl");
                eData[1] = result.getString("perso");
                eData[2] = result.getString("metier");
                eData[3] = result.getString("dinde");
                eData[4] = result.getString("pvp");

                expTable.add(eData.clone());
            }
        } catch (SQLException e) {
            e.printStackTrace();
            GameServer.writeLine("Failed !");

            SQLMgr.freeSQLQuery(result);
            SQLMgr.freeSQLStat(stat);
        }
        GameServer.writeLine("Ok !");

        SQLMgr.freeSQLQuery(result);
        SQLMgr.freeSQLStat(stat);
    }

    public static void loadRaces() {
        int i = 0;
        Statement stat = SQLMgr.createStat();
        ResultSet result = SQLMgr.query(stat, "SELECT * FROM race_db ORDER BY race");

        try {
            String[] rData = new String[14];

            while (result.next()) {
                i++;
                rData[0] = result.getString("race");
                rData[1] = result.getString("name");
                rData[2] = result.getString("startLife");
                rData[3] = result.getString("startPA");
                rData[4] = result.getString("startPM");
                rData[5] = result.getString("startInitiative");
                rData[6] = result.getString("startProspection");
                rData[7] = result.getString("weaponBonus");
                rData[8] = result.getString("intelligence");
                rData[9] = result.getString("chance");
                rData[10] = result.getString("agilite");
                rData[11] = result.getString("force");
                rData[12] = result.getString("vitalite");
                rData[13] = result.getString("sagesse");

                raceDatas.add(rData.clone());
            }
        } catch (SQLException e) {
            e.printStackTrace();
            GameServer.writeLine("Failed !");

            SQLMgr.freeSQLQuery(result);
            SQLMgr.freeSQLStat(stat);
        }
        GameServer.writeLine("Ok ! (loaded " + i + " races)");

        SQLMgr.freeSQLQuery(result);
        SQLMgr.freeSQLStat(stat);
    }

    public static void loadMaps() {
        int i = 0;
        Statement stat = SQLMgr.createStat();
        ResultSet result = SQLMgr.query(stat, "SELECT * FROM maps_data");

        try {
            while (result.next()) {
                i++;
                Map mapObject = new Map(result.getInt("ID"),
                        result.getInt("PosX"),
                        result.getInt("PosY"),
                        result.getInt("Width"),
                        result.getInt("Height"),
                        result.getInt("Subarea"),
                        result.getString("CreateTime"),
                        result.getString("MapData"),
                        result.getString("DecryptKey"), 
                        result.getString("Places"));
                
                mapDatas.put(result.getInt("ID"), mapObject);
                mapObject = null;
            }
        } catch (SQLException e) {
            e.printStackTrace();
            GameServer.writeLine("Failed !");

            SQLMgr.freeSQLQuery(result);
            SQLMgr.freeSQLStat(stat);
        }
        GameServer.writeLine("Ok ! (loaded " + i + " maps)");

        SQLMgr.freeSQLQuery(result);
        SQLMgr.freeSQLStat(stat);
    }

    public static void loadItems() {
        int i = 0;
        Statement stat = SQLMgr.createStat();
        ResultSet result = SQLMgr.query(stat, "SELECT * FROM items_data");

        try {
            while (result.next()) {
                i++;
                Item itemObject = new Item(result.getInt("ID"),
                        result.getString("Name"),
                        result.getInt("Type"),
                        result.getInt("Level"),
                        result.getInt("Weight"),
                        result.getString("WeaponInfo"),
                        result.getBoolean("TwoHands"),
                        result.getBoolean("IsEthereal"),
                        result.getBoolean("Forgemageable"),
                        result.getBoolean("IsBuff"),
                        result.getBoolean("Usable"),
                        result.getBoolean("Targetable"),
                        result.getInt("Price"),
                        result.getString("Conditions"),
                        result.getString("Stats"),
                        result.getString("UseEffects"));

                itemDatas.put(result.getInt("ID"), itemObject);
                itemObject = null;
            }
        } catch (SQLException e) {
            e.printStackTrace();
            GameServer.writeLine("Failed !");

            SQLMgr.freeSQLQuery(result);
            SQLMgr.freeSQLStat(stat);
        }
        GameServer.writeLine("Ok ! (" + i + " items loaded)");

        SQLMgr.freeSQLQuery(result);
        SQLMgr.freeSQLStat(stat);
    }

    public static void loadMapTriggers() {
        int i = 0;
        Statement stat = SQLMgr.createStat();
        ResultSet result = SQLMgr.query(stat, "SELECT * FROM maps_triggers");

        try {
            while (result.next()) {
                i++;
                Trigger triggerObject = new Trigger(result.getInt("id"),
                        result.getInt("MapID"),
                        result.getShort("CellID"),
                        result.getInt("NewMap"),
                        result.getShort("NewCell"));

                triggerDatas.put(result.getInt("id"), triggerObject);
                triggerObject = null;
            }
        } catch (SQLException e) {
            e.printStackTrace();
            GameServer.writeLine("Failed !");

            SQLMgr.freeSQLQuery(result);
            SQLMgr.freeSQLStat(stat);
        }
        GameServer.writeLine("Ok ! (" + i + " triggers loaded)");

        SQLMgr.freeSQLQuery(result);
        SQLMgr.freeSQLStat(stat);
    }
    
    public static void loadMonsters() {
        int i = 0;
        Statement stat = SQLMgr.createStat();
        ResultSet result = SQLMgr.query(stat, "SELECT * FROM creature_db");

        try {
            while(result.next()) 
            {   
                Statement statData = SQLMgr.createStat();
                ResultSet resultData = SQLMgr.query(statData, "SELECT * FROM creature_data WHERE Mob_Id = " + result.getInt("ID") + "");
                
                while(resultData.next())
                {
                	  i++;
                	  Monster monsterObject = new Monster(result.getLong("ID"),
                        result.getString("Name"),
                        result.getInt("Gfxid"),
                        result.getByte("Alignement"),
                        result.getString("Colors"),
                        result.getByte("AI_Type"),
                        result.getInt("Kamas_Dropped"),
                        result.getString("Breed"),
                        result.getByte("EcoSystem"),
                        resultData.getByte("Grade"),
                        resultData.getShort("Level"),
                        resultData.getShort("Pa"),
                        resultData.getShort("Pm"),
                        resultData.getInt("Life"),
                        resultData.getShort("rNeutral"),
                        resultData.getShort("rEarth"),
                        resultData.getShort("rFire"),
                        resultData.getShort("rWater"),
                        resultData.getShort("rAir"),
                        resultData.getShort("rPA"),
                        resultData.getShort("rPM"),
                        resultData.getInt("Sagesse"),
                        resultData.getInt("Force"),
                        resultData.getInt("Intelligence"),
                        resultData.getInt("Chance"),
                        resultData.getInt("Agilite"),
                        resultData.getString("Spells"));

                	monsterDatas.put(result.getInt("ID"), monsterObject);
                	monsterObject = null;
                }
                
                SQLMgr.freeSQLQuery(resultData);
                SQLMgr.freeSQLStat(statData);
            }
        } catch (SQLException e) {
            e.printStackTrace();
            GameServer.writeLine("Failed !");
            
            SQLMgr.freeSQLQuery(result);
            SQLMgr.freeSQLStat(stat);
        }
        GameServer.writeLine("Ok ! (" + i + " monsters loaded)");

        SQLMgr.freeSQLQuery(result);
        SQLMgr.freeSQLStat(stat);
    }

    public static void loadMapMonsterGroups() {
        int i = 0;
        Statement stat = SQLMgr.createStat();
        ResultSet result = SQLMgr.query(stat, "SELECT ID, Monsters, MaximumMonster, MaximumGroup FROM maps_data");

        try {
            while (result.next()) {
                if(!result.getString("Monsters").isEmpty())
                {
                	i++;
                	String[] monsters = result.getString("Monsters").split(",");
                	
                	for(int maxMonsterGroup = 0;maxMonsterGroup < result.getInt("MaximumGroup");maxMonsterGroup ++)
                	{
                		MonsterGroup monsterGroup = new MonsterGroup();
                		
	                	for(String monster : monsters)
	                	{
	                		monsterGroup.addMonster(getMonsterData().get(Integer.parseInt(monster)));
	                	}
	                	
	                	getMapData().get(result.getInt("ID")).addMonsterGroupOnMap(monsterGroup);
	                	monsterGroup = null;
                	}
                	getMapData().get(result.getInt("ID")).setMaxGroup(result.getInt("MaximumGroup"));
                	getMapData().get(result.getInt("ID")).setMaxMonsterByGroup(result.getInt("MaximumMonster"));
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
            GameServer.writeLine("Failed !");

            SQLMgr.freeSQLQuery(result);
            SQLMgr.freeSQLStat(stat);
        }
        GameServer.writeLine("Ok ! (" + i + " groups monster loaded)");

        SQLMgr.freeSQLQuery(result);
        SQLMgr.freeSQLStat(stat);
    }
    
    public static void loadSubAreas() {
        int i = 0;
        Statement stat = SQLMgr.createStat();
        ResultSet result = SQLMgr.query(stat, "SELECT * FROM subarea_data");

        try {
            while (result.next()) {
                i++;
                SubArea subAreaObject = new SubArea(result.getLong("id"),
                        result.getLong("area"),
                        result.getShort("alignment"));

                subAreaDatas.put(result.getLong("id"), subAreaObject);
                subAreaObject = null;
            }
        } catch (SQLException e) {
            e.printStackTrace();
            GameServer.writeLine("Failed !");

            SQLMgr.freeSQLQuery(result);
            SQLMgr.freeSQLStat(stat);
        }
        GameServer.writeLine("Ok ! (" + i + " subareas loaded)");

        SQLMgr.freeSQLQuery(result);
        SQLMgr.freeSQLStat(stat);
    }

    public static void loadSpells() {
        int i = 0;
        Statement stat = SQLMgr.createStat();
        ResultSet result = SQLMgr.query(stat, "SELECT * FROM spells_db");

        try {
            while (result.next()) {
                i++;
                Spell spellObject = new Spell(result.getLong("id"),
                        result.getString("name"),
                        result.getInt("sprite"), 
                        result.getString("spriteInfos"));
                
                spellObject.addSpellLevel(1, result.getString("lvl1"));
                spellObject.addSpellLevel(2, result.getString("lvl2"));
                spellObject.addSpellLevel(3, result.getString("lvl3"));
                spellObject.addSpellLevel(4, result.getString("lvl4"));
                spellObject.addSpellLevel(5, result.getString("lvl5"));
                spellObject.addSpellLevel(6, result.getString("lvl6"));

                spellDatas.put(result.getLong("id"), spellObject);
                spellObject = null;
            }
        } catch (SQLException e) {
            e.printStackTrace();
            GameServer.writeLine("Failed !");

            SQLMgr.freeSQLQuery(result);
            SQLMgr.freeSQLStat(stat);
        }
        GameServer.writeLine("Ok ! (" + i + " spells loaded)");

        SQLMgr.freeSQLQuery(result);
        SQLMgr.freeSQLStat(stat);
    }
    
    public static ArrayList<String[]> getExpData() {
        return expTable;
    }

    public static ArrayList<String[]> getRaceData() {
        return raceDatas;
    }

    public static Hashtable<Integer, Map> getMapData() {
        return mapDatas;
    }

    public static Hashtable<Integer, Trigger> getMapTriggerData() {
        return triggerDatas;
    }

    public static Hashtable<Integer, Item> getItemData() {
        return itemDatas;
    }
    
    public static Hashtable<Integer, Monster> getMonsterData() {
        return monsterDatas;
    }

    public static Hashtable<Long, SubArea> getSubAreaData() {
        return subAreaDatas;
    }
    
    public static Hashtable<Long, Spell> getSpellData() {
        return spellDatas;
    }
}
